// 列表数据转换为树形数据

/**
 *
 * @param list // 列表
 * @param parentId // 关联的上级id
 * @param id // id
 * @returns
 */

export const transformTree = (list: Array<any>, parentId: string, id: string): any[] => {
  const idObj: any = {};
  const parentIdObj: any = {};
  list.forEach((item) => {
    if (!idObj[item[id]]) {
      idObj[item[id]] = item;
    }

    if (!parentIdObj[item[parentId]]) {
      parentIdObj[item[parentId]] = { children: [item] };
    } else {
      parentIdObj[item[parentId]].children.push(item);
    }
  });

  // console.log(idObj, parentIdObj);
  const firstList: Array<any> = list.filter((item) => {
    if (parseInt(item[parentId]) === 0) {
      return true;
    }
    // 如果不是第一层节点
    if (item[parentId] !== 0 && !idObj[item[parentId]]) {
      return true;
    }
    return false;
  });

  // 递归生成树节点
  const generateTree = (arr) => {
    arr.forEach((item) => {
      if (parentIdObj[item[id]]) {
        item.children = parentIdObj[item[id]].children;
        generateTree(item.children);
      }
    });
  };

  generateTree(firstList);
  // console.log('treeList', firstList);

  // 如果有的是没有父级的数据就拼接再
  return firstList;

  // let number = 1; // 防止找不到有的数据格式错误导致无限循环，目前设置最多5层
  // let firstList: Array<any> = [];
  // let otherList: Array<any> = [];
  // list.forEach((item) => {
  //   item.children = [];
  //   // 如果是一级
  //   if (!parseInt(item[parentId])) {
  //     firstList.push(item);
  //   } else {
  //     otherList.push(item);
  //   }
  // });

  // // console.log(firstList.map((item) => item[id]), otherList.map((item) => item[parentId]));

  // const getTree = (parentList, arr) => {
  //   number += 1;
  //   const leftOver: Array<any> = [];
  //   let hasObj: Array<any> = [];
  //   arr.forEach((item) => {
  //     const obj = parentList.find((i) => i[id] === item[parentId]);

  //     if (obj) {
  //       obj.children.push(item);
  //       hasObj.push(item);
  //     } else {
  //       leftOver.push(item);
  //     }
  //   });

  //   if (leftOver.length !== 0 && number <= 5) {
  //     getTree(hasObj, leftOver);
  //   }
  // };

  // getTree(firstList, otherList);

  // return firstList;
};

// 树节点循环
export const forTree = (list: Array<any>, prop: 'children' | string, callback: Function) => {
  let children = prop || 'children';
  let flag = false;
  const fn = (arr) => {
    let isBreak = false;
    for (let i = 0; i < arr.length; i++) {
      const item = arr[i];
      flag = callback(item, arr, i);
      isBreak = flag;
      if (flag) {
        break;
      }
      if (item[children]?.length > 0) {
        isBreak = fn(item[children]);
        if (isBreak) {
          break;
        }
      }
    }
    return isBreak;
  };

  fn(list);

  return list;
};

// Promise 等待
export const sleep = (time: number = 0) => {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(1);
    }, time);
  });
};

export const shuffle = (arr: any[]) => {
  let i = arr.length;
  while (i) {
    let j = Math.floor(Math.random() * i--);
    [arr[j], arr[i]] = [arr[i], arr[j]];
  }
  return arr;
};

// 获取Url地址栏？后面的参数
export const getURLToObj = () => {
  const url = window.location.href;
  if (url.indexOf('?') === -1) {
    return {};
  }
  const str = window.location.href.split('?').pop();
  if (!str) {
    return {};
  }
  const arr = str.split('&');
  let obj = {};
  arr.forEach((s) => {
    const [key, value] = s.split('=');
    obj[decodeURIComponent(key)] = decodeURIComponent(value);
  });
  return obj;
};

// 获取hash url参数
export const getHashParams = () => {
  const hash = window.location.hash;
  let search = '';
  let pathname = '';
  let query = getURLToObj();
  if (hash.indexOf('?')) {
    [pathname, search] = hash.split('?');
    pathname = pathname.slice(1);
  } else {
    pathname = pathname.slice(1);
  }
  return { search, pathname, query };
};

// 创建音频条形图
export type IAudioMap = {
  draw: () => void;
  stopDraw: () => void;
};

export class AutioMap implements IAudioMap {
  canvas: HTMLCanvasElement | null = null;
  audioCtx: AudioContext;
  analyser: AnalyserNode;
  source: MediaStreamAudioSourceNode;
  distortion: WaveShaperNode;
  bufferLength: number;
  dataArray: Uint8Array;
  canvasCtx: CanvasRenderingContext2D | null;
  canvasHeight: number;
  canvasWidth: number;
  isDraw: boolean;

  constructor(canvas: HTMLCanvasElement, stream: MediaStream) {
    this.canvas = canvas;
    this.audioCtx = new (window.AudioContext || window.webkitAudioContext)();
    this.analyser = this.audioCtx.createAnalyser();
    this.analyser.minDecibels = -90;
    this.analyser.maxDecibels = -10;
    this.analyser.smoothingTimeConstant = 0.85;
    this.distortion = this.audioCtx.createWaveShaper();

    const gainNode = this.audioCtx.createGain();
    gainNode.gain.value = 1;
    const biquadFilter = this.audioCtx.createBiquadFilter();
    const convolver = this.audioCtx.createConvolver();
    this.source = this.audioCtx.createMediaStreamSource(stream);

    this.source.connect(this.distortion);
    this.distortion.connect(biquadFilter);
    biquadFilter.connect(gainNode);
    convolver.connect(gainNode);
    gainNode.connect(this.analyser);
    this.analyser.connect(this.audioCtx.destination);

    this.canvasCtx = this.canvas.getContext('2d');
    this.canvasWidth = this.canvas.clientHeight;
    this.canvasHeight = this.canvas.clientHeight;
    this.canvas.width = this.canvasWidth;
    this.canvas.height = this.canvasHeight;

    this.analyser.fftSize = 2048;
    this.bufferLength = this.analyser.frequencyBinCount;
    // console.log(this.bufferLength);
    this.dataArray = new Uint8Array(this.bufferLength);

    this.distortion.oversample = '4x';
    biquadFilter.gain.setTargetAtTime(0, this.audioCtx.currentTime, 0);

    biquadFilter.disconnect(0);
    biquadFilter.connect(gainNode);

    this.isDraw = true;
  }

  // 开始绘制
  draw = () => {
    if (this.isDraw) {
      this.analyser.getByteFrequencyData(this.dataArray);
      // console.log('dataArray', this.dataArray);

      this.canvasCtx!.clearRect(0, 0, this.canvasWidth, this.canvasHeight);
      this.canvasCtx!.fillStyle = 'rgba(0, 0, 0, 0)';
      this.canvasCtx!.fillRect(0, 0, this.canvasWidth, this.canvasHeight);

      let barWidth = (this.canvasWidth / this.bufferLength) * 6;
      let barHeight;
      let x = 0;

      for (let i = 0; i < this.bufferLength; i++) {
        barHeight = this.dataArray[i] / 2;
        // console.log('barHeight', barHeight, this.dataArray[i]);

        this.canvasCtx!.fillStyle = '#ff0';
        this.canvasCtx!.fillRect(x, this.canvasHeight / 2 - barHeight / 4, barWidth, barHeight / 4);
        this.canvasCtx!.fillRect(x, this.canvasHeight / 2 - barHeight / 4 + barHeight / 4, barWidth, barHeight / 4);

        x += barWidth + 3;
      }
      requestAnimationFrame(this.draw);
    }
  };

  // 停止绘制
  stopDraw = () => {
    this.isDraw = false;
  };

  makeDistortionCurve = (amount: number) => {
    var k = typeof amount === 'number' ? amount : 50,
      n_samples = 44100,
      curve = new Float32Array(n_samples),
      deg = Math.PI / 180,
      i = 0,
      x;
    for (; i < n_samples; ++i) {
      x = (i * 2) / n_samples - 1;
      curve[i] = ((3 + k) * x * 20 * deg) / (Math.PI + k * Math.abs(x));
    }
    return curve;
  };
}

// 判断当前环境是app内部还是浏览器
